#include "systemmainwindow.h"
#include "ui_systemmainwindow.h"

SysTemMainWindow::SysTemMainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SysTemMainWindow)
{
    ui->setupUi(this);
    initWindow();
}

SysTemMainWindow::~SysTemMainWindow()
{
    if(net != nullptr){
        delete net;
    }

    delete ui;
}

//初始化窗口
void SysTemMainWindow::initWindow()
{
    //使用STL标准库模板中的function，绑定SysTemMainWindow成员函数
    func[0] = std::bind(&SysTemMainWindow::setWeight, this, std::placeholders::_1);
    func[1] = std::bind(&SysTemMainWindow::setFiveTemperature, this, std::placeholders::_1);
    func[2] = std::bind(&SysTemMainWindow::setOpenHeater, this, std::placeholders::_1);
    func[3] = std::bind(&SysTemMainWindow::setOpenValve, this, std::placeholders::_1);
    func[4] = std::bind(&SysTemMainWindow::setPushbeamHeight, this, std::placeholders::_1);
    func[5] = std::bind(&SysTemMainWindow::setMotorRpm, this, std::placeholders::_1);
    func[6] = std::bind(&SysTemMainWindow::setStovePower, this, std::placeholders::_1);

    //读取配置文件，获取IP及端口号，获取上传数据json键
    QString ipcon = initReadConfig();
    net = new NetSet(ipcon);

    //获取单例对象指针用于存储数据
    dataPtr = std::unique_ptr<SaveData>(SaveData::getInstance());

    //连接主界面发送数据信号及存储模块存储数据槽
    connect(this,&SysTemMainWindow::mainSaveData,dataPtr.get(),&SaveData::saveData);

    //绑定历史数据文件打开失败信号及主界面提示槽
    connect(dataPtr.get(),&SaveData::saveDataOpenFileDefeat,this,&SysTemMainWindow::saveDataOpenFileDefeat);

    //主界面发送连接信号开始监听
    connect(this,&SysTemMainWindow::mainWindowSendNetCon,net,&NetSet::mainWindowListenCon);
    emit mainWindowSendNetCon();

    //监听失败时，主页面处理失败信息
    connect(net,&NetSet::netListenDefeat,this,&SysTemMainWindow::netListenDefeat);

    //连接成功时。主界面提示，并绑定主界面通信
    connect(net,&NetSet::netConnect,this,&SysTemMainWindow::netConnect);

    //连接断开时，主界面提示，并断开主界面控制
    connect(net,&NetSet::netDisconnect,this,&SysTemMainWindow::netDisconnect);
}

//初始化时读取ipconfig.txt获取ip及端口号，发射信号给网络设置
QString SysTemMainWindow::initReadConfig()
{
    QFile file("../measureSystem/etc/config.txt");
    if(!file.open(QIODevice::ReadOnly)){
        //qDebug() << "file open fail";
        QMessageBox::warning(this,"warn","file open fail",QMessageBox::Ok);
    }

    QTextStream in(&file);

    QString text;
    text = in.readLine();
    packType = in.readLine();
    keyUpdata = in.readLine().split(':');
    keyControl = in.readLine().split(':');
    keyRecvControl = in.readLine().split(':');

#if 0
    qDebug() << packType;
    qDebug() << keyUpdata;
    qDebug() << keyControl;
    qDebug() << keyRecvControl;
#endif

    file.close();

    return text;
}

QString SysTemMainWindow::setWeight(QString info)
{
    //将重量设置到界面上
    ui->weightLabel->setText(info);
    return info;
}

QString SysTemMainWindow::setFiveTemperature(QString info)
{
    QStringList temp = info.split('$');
    ui->tempLabel1->setText(temp[0]);
    ui->tempLabel2->setText(temp[1]);
    ui->tempLabel3->setText(temp[2]);
    ui->tempLabel4->setText(temp[3]);
    ui->tempLabel5->setText(temp[4]);

    QString tmp = QString("%1_%2_%3_%4_%5").arg(temp[0],temp[1],temp[2],temp[3],temp[4]);
    return tmp;
}

QString SysTemMainWindow::setOpenHeater(QString info)
{
    //关闭上次选中的按钮
    ui->plateRadioButton1->setChecked(false);
    ui->plateRadioButton2->setChecked(false);
    ui->plateRadioButton3->setChecked(false);
    ui->plateRadioButton4->setChecked(false);
    ui->plateRadioButton5->setChecked(false);

    QString tmp;
    //打开对应按钮
    switch (info.toInt()) {
    case 1:
        ui->plateRadioButton1->setChecked(true);
        tmp = "1_0_0_0_0";
        break;
    case 2:
        ui->plateRadioButton2->setChecked(true);
        tmp = "0_1_0_0_0";
        break;
    case 3:
        ui->plateRadioButton3->setChecked(true);
        tmp = "0_0_1_0_0";
        break;
    case 4:
        ui->plateRadioButton4->setChecked(true);
        tmp = "0_0_0_1_0";
        break;
    case 5:
        ui->plateRadioButton5->setChecked(true);
        tmp = "0_0_0_0_1";
        break;
    default:
        tmp = "0_0_0_0_0";
        break;
    }

    return tmp;
}

QString SysTemMainWindow::setOpenValve(QString info)
{
    //关闭上次选中的按钮
    ui->valveButtonOnOff1->setChecked(false);
    ui->valveButtonOnOff2->setChecked(false);
    ui->valveButtonOnOff3->setChecked(false);
    ui->valveButtonOnOff4->setChecked(false);
    ui->valveButtonOnOff5->setChecked(false);

    QString tmp;
    //打开对应按钮
    switch (info.toInt()) {
    case 1:
        ui->valveButtonOnOff1->setChecked(true);
        tmp = "1_0_0_0_0";
        break;
    case 2:
        ui->valveButtonOnOff2->setChecked(true);
        tmp = "0_1_0_0_0";
        break;
    case 3:
        ui->valveButtonOnOff3->setChecked(true);
        tmp = "0_0_1_0_0";
        break;
    case 4:
        ui->valveButtonOnOff4->setChecked(true);
        tmp = "0_0_0_1_0";
        break;
    case 5:
        ui->valveButtonOnOff5->setChecked(true);
        tmp = "0_0_0_0_1";
        break;
    default:
        tmp = "0_0_0_0_0";
        break;
    }

    return tmp;
}

QString SysTemMainWindow::setPushbeamHeight(QString info)
{
    ui->heightLabel->setText(info);

    return info;
}

QString SysTemMainWindow::setMotorRpm(QString info)
{
    ui->speedLabel->setText(info);

    return info;
}

QString SysTemMainWindow::setStovePower(QString info)
{
    ui->hotPowerLabel->setText(info);

    return info;
}

void SysTemMainWindow::netListenDefeat(QAbstractSocket::SocketError socketError)
{
    switch (socketError) {
        case QAbstractSocket::ConnectionRefusedError:
            QMessageBox::warning(this,"warn","服务器监听失败:Connection refused!", QMessageBox::Ok);
            //qDebug() << "Connection refused";
            break;
        case QAbstractSocket::RemoteHostClosedError:
            QMessageBox::warning(this,"warn","服务器监听失败:The remote host closed the connection!", QMessageBox::Ok);
            //qDebug() << "The remote host closed the connection";
            break;
        // 你可以扩展这个switch来处理其他错误类型
        default:
            QMessageBox::warning(this,"warn","服务器监听失败:An unknown error occurred!", QMessageBox::Ok);
            //qDebug() << "An unknown error occurred";
            break;
    }
}

void SysTemMainWindow::netConnect()
{
    //已连接，网络读取到数据时，主界面接收处理
    connect(net,&NetSet::netSetSendDataToMainWindow,this,&SysTemMainWindow::mainRecvNetJsonHandler);

    //已连接，主界面发送控制到网络
    connect(this,&SysTemMainWindow::mainSendControlNet,net,&NetSet::netSetRecvMainWindow);

    QMessageBox::information(this,"info","设备已连接",QMessageBox::Ok);
}

void SysTemMainWindow::netDisconnect()
{
    //已连接，网络读取到数据时，主界面接收处理
    disconnect(net,&NetSet::netSetSendDataToMainWindow,this,&SysTemMainWindow::mainRecvNetJsonHandler);

    //已连接，主界面发送控制到网络
    disconnect(this,&SysTemMainWindow::mainSendControlNet,net,&NetSet::netSetRecvMainWindow);

    QMessageBox::warning(this,"warn","设备已断开",QMessageBox::Ok);
}

void SysTemMainWindow::mainRecvNetJsonHandler(QString info)
{
    //解包并且反馈信息在界面上
    //qDebug() << "dev json:" << info;

    QJsonDocument doc = QJsonDocument::fromJson(info.toUtf8());

    QJsonObject root = doc.object();

    QString pack = root.value(packType).toString();
    QString data;
    if(pack == keyRecvControl[0]){
        qDebug() << "recv control";
    }else if(pack == keyUpdata[0]){
        //如果是上传数据，则解析，反馈在状态区
        //qDebug() << "updata";
        for(int i = 0; i < keyUpdata.size() - 1; i++){
            data += (this->func[i])(root.value(keyUpdata[i + 1]).toString());
            data += ",";
        }
        data += QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        //qDebug() << "save data:" << data;
        emit mainSaveData(data);
    }
}

void SysTemMainWindow::on_confirmButton_clicked()
{
    //获取主界面控制信息，组成json，发送到网络
    QJsonObject root;
    //组指令PackType
    root.insert(packType,keyControl[0]);

    //组OpenHeater
    if(ui->hotButton1->isChecked()){
        root.insert(keyControl[1],"1");
    }else if(ui->hotButton2->isChecked()){
        root.insert(keyControl[1],"2");
    }else if(ui->hotButton3->isChecked()){
        root.insert(keyControl[1],"3");
    }else if(ui->hotButton4->isChecked()){
        root.insert(keyControl[1],"4");
    }else if(ui->hotButton5->isChecked()){
        root.insert(keyControl[1],"5");
    }

    //组OpenValve 组OpenValveTime
    if(ui->valveButton1->isChecked()){
        root.insert(keyControl[2],"1");
        root.insert(keyControl[3],ui->valveSpinBox1->text());
    }else if(ui->valveButton2->isChecked()){
        root.insert(keyControl[2],"2");
        root.insert(keyControl[3],ui->valveSpinBox2->text());
    }else if(ui->valveButton3->isChecked()){
        root.insert(keyControl[2],"3");
        root.insert(keyControl[3],ui->valveSpinBox3->text());
    }else if(ui->valveButton4->isChecked()){
        root.insert(keyControl[2],"4");
        root.insert(keyControl[3],ui->valveSpinBox4->text());
    }else if(ui->valveButton5->isChecked()){
        root.insert(keyControl[2],"5");
        root.insert(keyControl[3],ui->valveSpinBox5->text());
    }

    //组PushbeamHeight
    root.insert(keyControl[4],ui->heightSpinBox->text());

    //组MotorDirection
    root.insert(keyControl[5],QString::number(1 - ui->directionBox->currentIndex()));

    //组SetTemp
    root.insert(keyControl[6],ui->tempSpinBox->text());

    QJsonDocument doc(root);

    QString json = doc.toJson();
    //qDebug() << "control json:" << json;

    emit mainSendControlNet(json);
}

void SysTemMainWindow::saveDataOpenFileDefeat(QFileDevice::FileError error)
{
    QString reason;
    switch (error) {
    case QFile::NoError:
        reason = "文件打开成功，不会发生这种情况";
        break;
    case QFile::ReadError:
        reason = "读取错误";
        break;
    case QFile::WriteError:
        reason = "写入错误";
        break;
    case QFile::FatalError:
        reason = "致命错误";
        break;
    case QFile::ResourceError:
        reason = "资源错误";
        break;
    case QFile::OpenError:
        reason = "打开文件时的错误";
        break;
    case QFile::AbortError:
        reason = "中止操作错误";
        break;
    case QFile::TimeOutError:
        reason = "操作超时错误";
        break;
    case QFile::UnspecifiedError:
        reason = "未指定错误";
        break;
    default:
        reason = "其他错误";
        break;
    }

    QMessageBox::warning(this,"warn","历史数据存储文件打开失败!\n原因:"+reason,QMessageBox::Ok);
}
